package com.scpii.universal.util;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.scpii.universal.constant.GenericConstants;
import com.scpii.universal.exception.GenericException;

/**
 * 文件上传工具类 universalWeb
 * 
 * @author liuhj 2012-7-10下午01:33:15
 */
public class FileUploadUtil {
	private static final String FAIL = "上传文件失败";
	private static final int BUFFER_SIZE = 16 * 1024;

	/**
	 * 文件上传
	 * 
	 * @param path
	 * @param request
	 * @author liuhj 
	 * 2012-7-12下午05:13:11
	 */
	public static void fileUpload(String path, HttpServletRequest request) {
		fileUpload(path, request, 0);
	}
	
	/**
	 * 文件上传
	 * 
	 * @param path
	 * @param request
	 * @author liuhj 
	 * 2012-7-12下午05:13:11
	 */
	public static void fileUpload(String path, HttpServletRequest request, int startOff) {
		InputStream inputStream = null;
		try {
			inputStream = request.getInputStream();
		} catch (IOException e) {
			throw new GenericException(FAIL);
		}
		FileOutputStream outputStream = null;
		try {
			outputStream = new FileOutputStream(new File(path));
		} catch (FileNotFoundException e) {
			throw new GenericException(FAIL+",目标路径:"+path);
		}

		int formlength = request.getContentLength();
		byte[] formcontent = new byte[formlength];
		int totalread = 0;
		int nowread = 0;
		while (totalread < formlength) {
			try {
				nowread = inputStream.read(formcontent, totalread, formlength);
			} catch (IOException e) {
				throw new GenericException(FAIL);
			}
			if (nowread == -1) 
				break;
			totalread += nowread;
		}

		try {
			outputStream.write(formcontent, 0, formlength-startOff);
			outputStream.flush();
			outputStream.close();
			inputStream.close();
		} catch (IOException e) {
			throw new GenericException(FAIL);
		}
	}
	
	/**
	 * 从流文件中获取请求参数
	 * @author Taylor
	 * 2012-11-27 上午09:46:26
	 * @param request
	 * @param headerLength
	 * @return
	 * String
	 */
	public static String getParamsFromRequest(HttpServletRequest request, int headerLength) {
		InputStream inputStream = null;
		try {
			inputStream = request.getInputStream();
			byte[] formcontent = new byte[512];
			inputStream.read(formcontent, 0, 512);
			return new String(formcontent);
		} catch (IOException e) {
			throw new GenericException(FAIL);
		}
	}
	
	/**
	 * 从流文件中获取请求参数
	 * @author Taylor
	 * 2012-11-27 上午09:46:26
	 * @param request
	 * @param headerLength
	 * @return
	 * String
	 */
	public static String getParamsFromRequest(HttpServletRequest request) {
		return getParamsFromRequest(request,GenericConstants.REQUEST_HEADER_LENGTH);
	}

	/**
	 * 文件拷贝
	 * @param srcPath
	 * @param targetPath
	 * @author liuhj
	 * 2012-7-12下午05:14:50
	 */
	public static void copy(String srcPath, String targetPath) {
		InputStream in = null;
		OutputStream out = null;
		try {
			in = new BufferedInputStream(new FileInputStream(srcPath),
					BUFFER_SIZE);
			out = new BufferedOutputStream(new FileOutputStream(targetPath),
					BUFFER_SIZE);
			byte[] buf = new byte[BUFFER_SIZE];
			while (in.read(buf) > 0) {
				out.write(buf);
			}
			out.close();
			in.close();
		} catch (FileNotFoundException e) {
			throw new GenericException(FAIL+",原路径:"+srcPath+",目标路径:"+targetPath);
		} catch (IOException e) {
			throw new GenericException(FAIL);
		} 
	}
	
	public static void compressPic(String outputFilePath,
			File inputFile, int outputWidth, int outputHeight) {
		try {
			Image img = ImageIO.read(inputFile);
			if (img == null)
				return;
			// 判断图片格式是否正确
			if (img.getWidth(null) == -1) {
				throw new GenericException(FAIL);
			} else {
				int newWidth;// 输出的图片宽度
				int newHeight; // 输出的图片高度
				double rate1 = 0;
				double rate2 = 0;
				// 为等比缩放计算输出的图片宽度及高度
				if (outputWidth > 0) 
					rate1 = ((double) img.getWidth(null)) / (double) outputWidth;
				if (outputHeight > 0)
					rate2 = ((double) img.getHeight(null)) / (double) outputHeight;
				// 根据缩放比率大的进行缩放控制
				double rate = rate1 > rate2 ? rate1 : rate2;
				if(outputWidth <= 0) {
					newWidth = img.getWidth(null);
				} else {
					newWidth = (int) (((double) img.getWidth(null)) / rate);
				}
				if(outputHeight <= 0) {
					newHeight = img.getHeight(null);
				} else {
					newHeight = (int) (((double) img.getHeight(null)) / rate);
				}
				String imgFormt = outputFilePath.substring(outputFilePath.lastIndexOf(".")+1);
				BufferedImage tag = null;
				if ("PNG".equalsIgnoreCase(imgFormt)) {
					tag = new BufferedImage((int) newWidth,
							(int) newHeight, BufferedImage.TYPE_INT_ARGB);
				} else {
					tag = new BufferedImage((int) newWidth,
							(int) newHeight, BufferedImage.TYPE_INT_RGB);
				}
				/*
				 * Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
				 */
				tag.getGraphics().drawImage(
						img.getScaledInstance(newWidth, newHeight,
								Image.SCALE_SMOOTH), 0, 0, null);
				FileOutputStream out = new FileOutputStream(outputFilePath);
				// JPEGImageEncoder可适用于其他图片类型的转换
//				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//				encoder.encode(tag);
				ImageIO.write(tag, imgFormt==null?"jpg":imgFormt, out);
				out.close();
			}
		} catch (IOException ex) {
			if (ex instanceof javax.imageio.IIOException){
				try {
					StreamUtil.uploadFileToServer(inputFile, outputFilePath);
				} catch (Exception e) {
					throw new GenericException("无法解析图片的色彩模式");
				}
			} else {
				throw new GenericException(FAIL);
			}
		}
	}
	
	/**
	 * 通过Ajax获取图片信息
	 * 
	 * @return
	 * @throws IOException
	 */
	public String ajaxGetImage(File inputFile, String filePath,
			String outputFilePath, int outputWidth, int outputHeight)
			throws Exception {
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/plain");
		response.setCharacterEncoding("utf-8");
		if (inputFile != null) {
			compressPic(outputFilePath, inputFile, outputWidth,outputHeight);
			Image img = ImageIO.read(inputFile);
			response.getWriter().print(
					"图片#" + filePath + "#" + img.getWidth(null) + "#"
							+ img.getHeight(null));// 把相应的地址放到前台解析，通过#符号分割
		} else {
			response.getWriter().print("图片上传失败!");
		}
		return null;
	}
	
	/**
	 * 生成临时文件名前缀
	 * @return
	 * @author liuhj
	 * 2012-7-12下午05:47:56
	 */
	public static String generateIconName() {
		char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
				'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
				'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6',
				'7', '8', '9' };
		Random random = new Random();
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < 16; i++) {
			buf.append(codeSequence[random.nextInt(36)]);
		}
		return buf.toString();
	}
}
